// Top Module for VCS and Verdi
module sim_soc();

wire   [1:0]    core_in_core_id;
wire   [7:0]    core_in_interrupt;
wire            core_in_ipi;
wire            uart_txd;

reg clk;
initial begin 
  clk = 0;
  forever begin
    #(2) clk = ~clk;
  end
end

reg reset;
initial begin
  reset = 0;
  #10;
  reset = 1;
  #80;
  reset = 0;
end

`define  DUMMY_LOG

reg [47:0] cpu_awaddr;
reg [3:0]  cpu_awlen;
reg [15:0] cpu_wstrb;
reg        cpu_wvalid;
reg        cpu_wready;
reg [63:0] value0;
reg [63:0] value1;
reg [63:0] value2;

always @(posedge clk)
begin
  cpu_awlen[3:0]   <= soc_wrap.core_io_axi_aw_payload_len[3:0];
  cpu_awaddr[47:0] <= soc_wrap.core_io_axi_aw_payload_addr[47:0];
  cpu_wvalid       <= soc_wrap.core_io_axi_w_valid;
  cpu_wready       <= soc_wrap.toplevel_core_io_axi_writeOnly_w_ready;
  cpu_wstrb        <= soc_wrap.core_io_axi_w_payload_strb;
  value0           <= soc_wrap.core_io_axi_w_payload_data[63:0];
  value1           <= soc_wrap.core_io_axi_w_payload_data[127:64];
end



`ifdef DUMMY_LOG
always @(posedge clk) begin
     if ((cpu_awlen[3:0] == 4'b0) &&
         (cpu_awaddr[31:0] == 32'h1FF1_0000) &&
          cpu_wvalid &&
          cpu_wready
     ) begin
        if(cpu_wstrb[15:0] == 16'hf) 
           begin
              $write("%c", soc_wrap.core_io_axi_w_payload_data[7:0]);
           end
        else if(cpu_wstrb[15:0] == 16'hf0)
           begin
              $write("%c", soc_wrap.core_io_axi_w_payload_data[39:32]);
           end
        else if(cpu_wstrb[15:0] == 16'hf00)
           begin
              $write("%c", soc_wrap.core_io_axi_w_payload_data[71:64]);
           end
        else if(cpu_wstrb[15:0] == 16'hf000)
           begin
              $write("%c", soc_wrap.core_io_axi_w_payload_data[103:96]);
           end
    end
end
`endif


assign core_in_core_id = {1'b0, 1'b0};
assign core_in_interrupt = {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
assign core_in_ipi = 1'b0;


reg sys_exit;

`ifdef DUMMY_LOG
always @(posedge clk) begin
     if ((cpu_awaddr[31:0] == 32'h1FF8_0000) &&
          cpu_wvalid &&
          cpu_wready
     ) begin
        if(cpu_wstrb[15:0] == 16'hff &&
            soc_wrap.core_io_axi_w_payload_data[7:0] == 8'b00001111) 
           begin
              sys_exit <= 1;
              $finish;
           end
    end
end
`endif


// initial begin
//         #600000
//         $finish;
// end


`ifdef VERDI_DUMP
initial begin
      /// method 1: this will dump only ct_top module
      $fsdbDumpon;
      $fsdbDumpvars(0, sim_soc);

      /// method 2: this will dump all module
      // $fsdbDumpvars();
end
`endif


wire            axi_aw_valid;
wire            axi_aw_ready;
wire   [47:0]   axi_aw_addr;
wire   [4:0]    axi_aw_id;
wire   [7:0]    axi_aw_len;
wire   [2:0]    axi_aw_size;
wire   [1:0]    axi_aw_burst;
wire   [3:0]    axi_aw_cache;
wire   [2:0]    axi_aw_prot;
wire            axi_w_valid;
wire            axi_w_ready;
wire   [127:0]  axi_w_data;
wire   [15:0]   axi_w_strb;
wire            axi_w_last;
wire            axi_b_valid;
wire            axi_b_ready;
wire   [4:0]    axi_b_id;
wire   [1:0]    axi_b_resp;
wire            axi_ar_valid;
wire            axi_ar_ready;
wire   [47:0]   axi_ar_addr;
wire   [4:0]    axi_ar_id;
wire   [7:0]    axi_ar_len;
wire   [2:0]    axi_ar_size;
wire   [1:0]    axi_ar_burst;
wire   [3:0]    axi_ar_cache;
wire   [2:0]    axi_ar_prot;
wire            axi_r_valid;
wire            axi_r_ready;
wire   [127:0]  axi_r_data;
wire   [4:0]    axi_r_id;
wire   [1:0]    axi_r_resp;
wire            axi_r_last;


assign  axi_aw_ready = 0;
assign  axi_w_ready = 0;
assign  axi_b_valid = 0;
assign  axi_b_id = 0;
assign  axi_b_resp = 0;
assign  axi_ar_ready = 0;
assign  axi_r_valid = 0;
assign  axi_r_data = 0;
assign  axi_r_id = 0;
assign  axi_r_resp = 0;
assign  axi_r_last = 0;

Soc soc_wrap(
        .clk                     (clk),
        .reset                   (reset),
        .io_axi_aw_valid         (axi_aw_valid),
        .io_axi_aw_ready         (axi_aw_ready),
        .io_axi_aw_payload_addr  (axi_aw_addr),
        .io_axi_aw_payload_id    (axi_aw_id),
        .io_axi_aw_payload_len   (axi_aw_len),
        .io_axi_aw_payload_size  (axi_aw_size),
        .io_axi_aw_payload_burst (axi_aw_burst),
        .io_axi_aw_payload_cache (axi_aw_cache),
        .io_axi_aw_payload_prot  (axi_aw_prot),
        
        .io_axi_w_valid          (axi_w_valid),
        .io_axi_w_ready          (axi_w_ready),
        .io_axi_w_payload_data   (axi_w_data),
        .io_axi_w_payload_strb   (axi_w_strb),
        .io_axi_w_payload_last   (axi_w_last),
        
        .io_axi_b_valid          (axi_b_valid),
        .io_axi_b_ready          (axi_b_ready),
        .io_axi_b_payload_id     (axi_b_id),
        .io_axi_b_payload_resp   (axi_b_resp),
        
        .io_axi_ar_valid         (axi_ar_valid),
        .io_axi_ar_ready         (axi_ar_ready),
        .io_axi_ar_payload_addr  (axi_ar_addr),
        .io_axi_ar_payload_id    (axi_ar_id),
        .io_axi_ar_payload_len   (axi_ar_len),
        .io_axi_ar_payload_size  (axi_ar_size),
        .io_axi_ar_payload_burst (axi_ar_burst),
        .io_axi_ar_payload_cache (axi_ar_cache),
        .io_axi_ar_payload_prot  (axi_ar_prot),
        
        .io_axi_r_valid          (axi_r_valid),
        .io_axi_r_ready          (axi_r_ready),
        .io_axi_r_payload_data   (axi_r_data),
        .io_axi_r_payload_id     (axi_r_id),
        .io_axi_r_payload_resp   (axi_r_resp),
        .io_axi_r_payload_last   (axi_r_last),
        
        .io_core_in_core_id      (core_in_core_id),
        .io_core_in_interrupt    (core_in_interrupt),
        .io_core_in_ipi          (core_in_ipi)
    );


reg [7:0] uart_char_buffer;


`define BAUD_PERIOD 1000000
`ifndef DUMMY_LOG

reg uart_clk;

always @(posedge clk) begin : proc_
  if(reset) begin
      uart_char_buffer <= 0;
  end else if(uart_txd) begin
      uart_char_buffer <= uart_char_buffer | 1 << count;
  end 

  if (reset || count == 3'b111 || ~uart_start) begin
    count <= 0;
  end else if (uart_start) begin
    count <= count + 1;
  end
end
`endif

endmodule